# this script generates measures of defensive ownership:
# (no) oligarch in chain; foreign in chain; offshore in chain
# for oligarch in chain, check paths only 
# to oligarchs from the group assigned to each firm by Delo/UP

# load the list of countries designated as offshores
offshore_codes <- read_csv("Additional Data/offshore_codes.csv")

# create a list of all foreign firms in the extracted ownership links
foreign_firms <- all.ids %>% 
  filter(entity == "corporate", country != 804) %>% 
  pull(id) %>% unique()
foreign_firms_codes <- all.ids %>%
  filter(entity == "corporate" & country != 804) %>%
  select(id, country, entity_name)

# create a list of the main oligarch-controlled firms;
# we will check all other entities for ownership links with these firms
step0_firms <- all.ids %>% 
  filter(step == 0) %>% 
  pull(id) %>% unique()

# create a data frame that will be populated with defensive ownership measures
# for the main oligarch-controlled firms
DUP_firms <- all.ids %>% filter(id %in% step0_firms) %>%
  dplyr::select("id", "entity_name", 
                "group", group_list) %>%
  mutate(okpo = as.numeric(substr(id, 3, nchar(id))),
         shortest_path_foreign = NA,
         foreign_in_chain = NA,
         offshore_in_chain = NA,
         shortest_path_oligarch = NA,
         oligarch_in_chain = NA,
         foreign_entities_countries = NA)

# create a data frame that will be populated with data on foreign owners
# (used in some supplementary analyses)
DUP_foreign_owners <- tibble(okpo = as.numeric(), foreign_owner_name = as.character(), 
                             foreign_owner_country = as.numeric())

# examine paths to oligarch-controlled firms from oligarchs and foreign firms
for (i in 1:nrow(DUP_firms)) {
  firm <- DUP_firms$id[i]
  print(paste(i, firm))
  
  # get identifiers for oligarchs within a particular group
  firm_group <- all.ids %>% 
    filter(id == firm) %>%
    pull(group)
  
  if (firm_group == "double SCM/ISD") {
    oligarchs_same_group <- all.ids %>%
      filter(oligarch == "oligarch", 
             group_oligarch == "SCM" | group_oligarch == "ISD") %>%
      pull(id)
    
  } else if (firm_group == "double ISD/Pryvat") {
    oligarchs_same_group <- all.ids %>%
      filter(oligarch == "oligarch", 
             group_oligarch == "Pryvat" | group_oligarch == "ISD") %>%
      pull(id)
    
  } else {
    oligarchs_same_group <- all.ids %>%
      filter(oligarch == "oligarch", group_oligarch == firm_group) %>%
      pull(id)
  }
  
  # extract paths from oligarchs
  spaths_oligarch <- shortest_paths(o.network.D, firm, 
                                    oligarchs_same_group, mode = "in")
  # extract paths from foreign firms
  spaths_foreign <- shortest_paths(o.network.D, firm, 
                                   foreign_firms, mode = "in")

  # calculate the length of paths from oligarchs
  shortest_path_oligarch <- unlist(lapply(spaths_oligarch$vpath, length))
  shortest_path_oligarch <- 
    ifelse(max(shortest_path_oligarch) > 0,
           min(shortest_path_oligarch[shortest_path_oligarch != 0] - 1),
           NA)
  DUP_firms$shortest_path_oligarch[i] <- shortest_path_oligarch
  
  # when path exists, oligarch in chain is set to 1
  DUP_firms$oligarch_in_chain[i] <- 1 - is.na(shortest_path_oligarch)

  # calculate the length of paths from foreign firms
  shortest_path_foreign <- unlist(lapply(spaths_foreign$vpath, length))
  shortest_path_foreign <-
    ifelse(max(shortest_path_foreign) > 0,
           min(shortest_path_foreign[shortest_path_foreign != 0]-1),
           NA)
  DUP_firms$shortest_path_foreign[i] <- shortest_path_foreign

  # when path exists, foreign in chain is set to 1
  DUP_firms$foreign_in_chain[i] <- 1 - is.na(shortest_path_foreign)
  
  # if any of the foreign entities in chain are offshore,
  # set offshore in chain to 1
  foreign_entities <- unique(unlist(lapply(spaths_foreign$vpath, names)))
  foreign_entities <- foreign_entities[foreign_entities %in% foreign_firms]
  foreign_entities_countries <- foreign_firms_codes %>%
    filter(id %in% foreign_entities) %>%
    pull(country) %>% unique()
  DUP_firms$offshore_in_chain[i] <- 
    sum(any(foreign_entities_countries %in% offshore_codes$country_code))
  
  # save all countries of foreign entities in chain
  DUP_firms$foreign_entities_countries[i] <- paste(foreign_entities_countries,
                                                   collapse = "|")
  
  # update the data frame with foreign owners
  if (length(foreign_entities) > 0) {
    firm_foreign_owners <- tibble(okpo = as.numeric(substr(firm, 3, nchar(firm))),
                                  id = foreign_entities) %>%
      left_join(foreign_firms_codes) %>%
      select(-id) %>%
      rename(foreign_owner_name = entity_name,
             foreign_owner_country = country)
    DUP_foreign_owners <- bind_rows(DUP_foreign_owners, firm_foreign_owners)
  }
}

# add dummy: whether oligarch-controlled firms are present in JSCReg/SReg 
# (affects the composition of the sample later)
JS_presence <- read_dta(paste0("Ownership Data/Delo_UP_present_JSCReg_SReg_", 
                               search_date, ".dta")) %>%
  select(-c(present_SReg, present_JSCReg))
DUP_firms <- left_join(DUP_firms, JS_presence)

# add dummy: whether a firm has owners in the network graph
has_owners <- all.ids %>% 
  filter(step == 0) %>% select(id) %>%
  mutate(has_owners = if_else(id %in% all.edges$sub, 1, 0))
DUP_firms <- left_join(DUP_firms, has_owners)

# set foreign in chain/offshore in chain to NA if firm not present in SReg/JSCReg
DUP_firms <- DUP_firms %>%
  mutate(foreign_in_chain = as.numeric(foreign_in_chain),
         offshore_in_chain = as.numeric(offshore_in_chain),
         foreign_in_chain = case_when(
    present_JSCReg_SReg == 0 ~ NA_real_,
    present_JSCReg_SReg == 1 & is.na(foreign_in_chain) ~ 0,
    TRUE ~ foreign_in_chain
  ),
  offshore_in_chain = case_when(
    present_JSCReg_SReg == 0 ~ NA_real_,
    present_JSCReg_SReg == 1 & is.na(offshore_in_chain) ~ 0,
    TRUE ~ offshore_in_chain
  ))

# save data files
write_dta(DUP_firms, paste0("Network Data/DUP_hiding_", 
                            search_date, ".dta"))
write_dta(DUP_foreign_owners, paste0("Network Data/DUP_foreign_owners_", 
                                     search_date, ".dta"))
